package com.molichuxing.services.infrastructure.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.services.infrastructure.bean.PaymentBean;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dao.PaymentMapper;
import com.molichuxing.services.infrastructure.dto.request.create.PaymentCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.PaymentModifyDto;
import com.molichuxing.services.infrastructure.dto.response.PaymentDto;
import com.molichuxing.services.infrastructure.service.PaymentService;
import com.molichuxing.services.property.PaymentCostTypeEnum;
import com.molichuxing.services.property.PaymentStatusEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 支付回传 服务实现类
 * </p>
 *
 * @author zhaopenghui
 * @since 2019-08-23
 */
@Service("paymentService")
public class PaymentServiceImpl implements PaymentService {

    @Resource
    PaymentMapper paymentMapper;

    /**
     * 支付新增
     *
     * @param paymentCreateDto
     * @return id
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Integer createPayment(PaymentCreateDto paymentCreateDto) throws Exception {
        PaymentBean paymentBean = Convert.toPaymentBean(paymentCreateDto);
        paymentMapper.create(paymentBean);
        return paymentBean.getId();
    }


    /**
     * 线下支付分页列表
     *
     * @param params   key:businessType Integer 业务类型（1：订阅，2：专属：3：经销商）
     *                 key:orderCode Long 订单号
     *                 key:thirdPayNumber String 付款流水号
     *                 key:userId Integer 用户id
     *                 key:startPayTime LocalDateTime 付款开始时间
     *                 key:endPayTime LocalDateTime 付款结束时间
     *                 key:payWay Integer 支付方式
     *                 key:payType 支付类型（1：订购，2：加购，3：结算，4：还款）
     *                 key:status 支付状态(0：待支付，1:成功，2：失败)
     *                 key:ids List<Integer> 支付id集合
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<PaymentDto> getPaymentPage(Map<String, Object> params, Integer pageNum, Integer pageSize)
            throws Exception {
        // 转换时间
        params.put("startPayTime", ObjectCastUtil.castLocalDateTimeStart(params.get("startPayTime")));
        params.put("endPayTime", ObjectCastUtil.castLocalDateTimeEnd(params.get("endPayTime")));

        long total = paymentMapper.getPageCount(params);
        List<PaymentBean> page = null;
        if (total > 0) {
            page = paymentMapper.getPage(params, pageNum, pageSize);
        }

        return new Paged<PaymentDto>(Convert.toPaymentDto(page), total, pageSize);
    }

    /**
     * 根据订单号，支付状态，支付类型查询支付信息
     *
     * @param orderCode
     * @param status
     * @param payType
     * @return
     */
    @Override
    public List<PaymentDto> getListByOrderCode(Long orderCode, Integer status, Integer payType) {
        return Convert.toPaymentDto(paymentMapper.getListByOrderCode(orderCode, status, payType));
    }

    /**
     * 查询支付信息
     *
     * @param userId    用户id
     * @param payStatus 支付状态
     * @return
     */
    @Override
    public List<PaymentDto> getPaymentByUser(Integer userId, PaymentStatusEnum payStatus) {
        return Convert
                .toPaymentDto(paymentMapper.getPaymentByUser(userId, payStatus == null ? null : payStatus.getValue()));
    }

    /**
     * 查询支付信息
     *
     * @param orderCode 订单号
     * @return
     */
    @Override
    public PaymentDto getPaymentByOrder(Long orderCode) {
        List<PaymentBean> list = paymentMapper.getPaymentByOrder(orderCode, null);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return Convert.toPaymentDto(list.get(0));
    }

    /**
     * 查询支付信息
     *
     * @param orderCode  订单号
     * @param scheduleId 排期id
     * @return
     */
    @Override
    public PaymentDto getPaymentByOrder(Long orderCode, Integer scheduleId) {
        List<PaymentBean> list = paymentMapper.getPaymentByOrder(orderCode, scheduleId);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return Convert.toPaymentDto(list.get(0));
    }

    /**
     * 修改支付单信息
     *
     * @param modifyDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modify(PaymentModifyDto modifyDto) {
        if (paymentMapper.modify(Convert.toPaymentBean(modifyDto)) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 查询支付单信息
     *
     * @param payNumber 付款流水号
     * @return
     */
    @Override
    public PaymentDto getPayment(String payNumber) {
        return Convert.toPaymentDto(paymentMapper.getPaymentByPayNumber(payNumber));
    }

    /**
     * 支付完成修改支付单信息
     *
     * @param modifyDto
     * @return
     */
    @Override
    public boolean modifyPayResult(PaymentModifyDto modifyDto) {
        if (paymentMapper.modifyPaySuccess(Convert.toPaymentBean(modifyDto)) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 查询支付单信息
     *
     * @param orderCode  订单号
     * @param scheduleId 排期id
     * @param costType   费用类型
     * @return
     */
    @Override
    public PaymentDto getPaymentByOrder(Long orderCode, Integer scheduleId, PaymentCostTypeEnum costType) {
        return Convert
                .toPaymentDto(paymentMapper.getPaymentByOrderAndCostType(orderCode, scheduleId, costType.getValue()));
    }

    /**
     * 通过业务类型查询数量
     *
     * @return
     * @throws Exception
     */
    @Override
    public Map<Integer, Integer> getPaymentCountByBusinessType() throws Exception {
        List<TabDto> statusList = paymentMapper.getPaymentCountByBusinessType();
        if (null == statusList || statusList.size() == 0) {
            return null;
        }

        Map<Integer, Integer> returnMap = new HashMap<Integer, Integer>();
        for (TabDto tabDto : statusList) {
            Integer type = tabDto.getType();
            Integer count = tabDto.getCount();
            returnMap.put(type, count);
        }

        return returnMap;
    }

    /**
     * 查询支付成功信息
     *
     * @param selectParams
     * @return
     */
    @Override
    public List<PaymentDto> getPaymentSuccessList(Map<String, Object> selectParams) {
        // 转换时间
        selectParams.put("startPayTime", ObjectCastUtil.castLocalDateTimeStart(selectParams.get("startPayTime")));
        selectParams.put("endPayTime", ObjectCastUtil.castLocalDateTimeEnd(selectParams.get("endPayTime")));
        //
        selectParams.put("payStatus", PaymentStatusEnum.SUCCESS_PAYMENT.getValue());
        return Convert.toPaymentDto(paymentMapper.getPaymentList(selectParams));
    }

    /**
     * 查询支付成功信息条数
     *
     * @param selectParams
     * @return
     */
    @Override
    public Long getPaymentSuccessListCount(Map<String, Object> selectParams) {
        // 转换时间
        selectParams.put("startPayTime", ObjectCastUtil.castLocalDateTimeStart(selectParams.get("startPayTime")));
        selectParams.put("endPayTime", ObjectCastUtil.castLocalDateTimeEnd(selectParams.get("endPayTime")));
        selectParams.put("payStatus", PaymentStatusEnum.SUCCESS_PAYMENT.getValue());
        return paymentMapper.getPaymentListCount(selectParams);
    }

    /**
     * 查询支付成功信息
     *
     * @param orderCode 订单号
     * @param costType  支付类型
     * @return
     */
    @Override
    public List<PaymentDto> getSuccessPayment(Long orderCode, PaymentCostTypeEnum costType) {
        return Convert
                .toPaymentDto(paymentMapper.getSuccessPaymentByOrderCode(orderCode, costType == null ? null : costType.getValue(),
                        PaymentStatusEnum.SUCCESS_PAYMENT.getValue()));

    }

    /**
     * 线下支付修改支付信息
     *
     * @param modifyDto
     * @return
     */
    @Override
    public boolean modifyOffline(PaymentModifyDto modifyDto) {
        return paymentMapper.modifyOffline(Convert.toPaymentBean(modifyDto)) > 0;
    }
}
